package com.x9space.framework.elastic.handler;

import com.x9space.common.utils.StringUtils;
import com.x9space.framework.elastic.annotation.RangeMatch;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

public class RangeMatchQueryHandler extends QueryHandler {


    @Override
    public String getName() {
        return "RangeMatch";
    }

    @Override
    protected QueryBuilder _doHandle(Annotation annotation, Map<String,Object> context) {
        if (!(annotation instanceof RangeMatch)) {
            return null;
        }
        RangeMatch item = (RangeMatch) annotation;

        String field = item.field();
        if (StringUtils.isEmpty(field)){
            field = ((Field)context.get("field")).getName();
        }

        Object value = context.get("value");
        Class<?> clazz = value.getClass();

        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(field);
        Class<?> componentType = clazz.getComponentType();
        if (componentType != null) {
            Object[] array = (Object[]) context.get("value");
            if (array.length!= 2){
                return null;
            }

            if (item.gt()){
                rangeQueryBuilder.gt(array[0]);
            }
            if (item.gte()){
                rangeQueryBuilder.gte(array[0]);
            }

            if (item.lt()){
                rangeQueryBuilder.lt(array[1]);
            }
            if (item.lte()){
                rangeQueryBuilder.lte(array[1]);
            }

        } else if (value instanceof Iterable) {
            Iterable iterable = (Iterable) value;
            Iterator iterator = iterable.iterator();
            ArrayList<Object> list = new ArrayList<>();
            while (iterator.hasNext()) {
                list.add(iterator.next());
            }
            if (list.size()!=2){
                return null;
            }
            if (item.gt()){
                rangeQueryBuilder.gt(list.get(0));
            }
            if (item.gte()){
                rangeQueryBuilder.gte(list.get(0));
            }

            if (item.lt()){
                rangeQueryBuilder.lt(list.get(1));
            }
            if (item.lte()){
                rangeQueryBuilder.lte(list.get(1));
            }

        } else {
            if (item.gt()){
                rangeQueryBuilder.gt(value);
            } else if (item.lt()){
                rangeQueryBuilder.lt(value);
            } else if (item.gte()){
                rangeQueryBuilder.gte(value);
            } else if (item.lte()){
                rangeQueryBuilder.lte(value);
            }
        }
        if (!StringUtils.isBlank(item.format())){
            rangeQueryBuilder.format(item.format());
        }
        if (!StringUtils.isBlank(item.timeZone())){
            rangeQueryBuilder.timeZone(item.timeZone());
        }
        if (item.boost()>=0){
            rangeQueryBuilder.boost(item.boost());
        }
        return rangeQueryBuilder;
    }
}
